<?php

// Namespace

namespace Loop;


// Dependencies

require_once(PATH_LOOP . 'Component/SimpleTest/1.1/unit_tester.php');
require_once(PATH_LOOP . 'Component/SimpleTest/1.1/reporter.php');


/**
 * CTestManager is a class that handles execution of unit tests and reporting of results.
 */

class CTestManager
{
	// Constants
	
	const REPORTER_HTML = 'HtmlReporter';
	const REPORTER_XML = 'XmlReporter';
	
	
	/**
	 * Performs unit tests for the application and all extensions
	 *
	 * @param	string 	$testName		The name of the test that should be run (null by default, runs all tests)
	 * @param	bool	$fullTest		True to perform a full test, false otherwise
	 * @param	string	$reporterClass 	The class of the reporter. XML by default.
	 *
	 * @return	array 	A report of the test
	 */
	
	public function run($testName = null, $fullTest = true, $reporterClass = CTestManager::REPORTER_XML)
	{
		// Get the extensions

		$extensionsIds = app()->getExtensionManager()->getExtensionsIds();



		// For each extension found, redefine database to user

		foreach ($extensionsIds as $extensionId)
		{
			$databaseName = pref('['.$extensionId.']/database/name') . '_test';
			

			// Change the databaseName

			pref('['.$extensionId.']/database/name', $databaseName);
		}


		// Forge the database

		if
		(
			$fullTest == true ||
			$fullTest == '1'
		)
		{
			app()->getApplicationFactory()->forge(false, $extensionsIds);
		}
		else
		{
			app()->getApplicationFactory()->clean(false);
		}

		
		// Get paths of extensions + application
		
		$pathsToExtensions = app()->getExtensionManager()->getPathsToExtensions();
		
		// For each path, find tests available
		
		$testSuite = new \TestSuite();

		foreach ($extensionsIds as $extensionId)
		{
			$pathToExtension = app()->getPathHelper()->convertExtensionIdToPath($extensionId);


			// Find files under the Test directory
			
			if (empty($testName) == true)
			{
				$testName = '*';
			}
			
			$pathToTests = $pathToExtension . 'Test/';
			$pattern = $testName . '_Test' . '.php';
			$pathsToTests = app()->getFileHelper()->listFiles($pathToTests, $pattern);
			
			
			// Add each test to the suite of tests
			
			foreach ($pathsToTests as $pathToTest)
			{
				// Create the test
				
				require_once($pathToTest);
				
				$className = str_replace(array($pathToTests, '.php'), '', $pathToTest);

				// Is there a namespace ?
				
				if (class_exists($className) === false)
				{
					$className = app()->getPathHelper()->convertExtensionIdToNamespace($extensionId) . $className;
				}

				$test = new $className();
				
				
				// Add it to the suite
				
				$testSuite->add($test);
			}
		};
		
		
		// We can now run all tests!
		
		ob_start();
		
		$reporter = new $reporterClass();

		$testSuite->run($reporter);
		
		$rawOutput = ob_get_contents();
		
		ob_end_clean();
		
		
		
		// Prepare the trace
		
		$trace = $rawOutput;
		
		if ($reporterClass == CTestManager::REPORTER_XML)
		{
			$xml = simplexml_load_string($rawOutput);
			$trace = app()->getStringHelper()->convertXmlToArray($xml);
		}
		
		
		// Prepare the report of the test
		
		$result = array
		(
			'nbExceptions' => $reporter->getExceptionCount(),
			'nbFails' => $reporter->getFailCount(),
			'nbPasses' => $reporter->getPassCount(),
			'status' => $reporter->getStatus(),
			'trace' => $trace
		);
		
		
		return $result;
	}
}

?>
